using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace ArkanoidX
{
    /// <summary>
    /// This is a _game component that implements IUpdateable.
    /// </summary>
    public partial class Brick : StatefulComponent
    {
        public abstract class State : StatefulComponent.State<Brick>
        {
            public State(Texture2D texture, Vector2 size)
                : base(texture, size, new Rectangle(0, 0, texture.Width, texture.Height))
            {
            }

            public State(Texture2D texture)
                : base(texture, new Vector2(texture.Width, texture.Height), 
                new Rectangle(0, 0, texture.Width, texture.Height))
            {
            }
        }

        Vector2 _position;

        Bricks _parent;

        public State[] _states;
        public int _iCurrentState;        // index to the current state of the racket

        public State CurrentState { get { return _states[_iCurrentState]; } }

        public Vector2 Position
        {
            get { return _position; }
        }

        // Rectangle that contains the shape in the game world
        public Rectangle Rectangle
        {
            get
            {
                float halfWidth = CurrentState.Size.X * 0.5f;
                float halfHeight = CurrentState.Size.Y * 0.5f;
                return new Rectangle(
                    (int)Math.Floor(_position.X - halfWidth),
                    (int)Math.Floor(_position.Y - halfHeight),
                    (int)Math.Ceiling(CurrentState.Size.X),
                    (int)Math.Ceiling(CurrentState.Size.Y));
            }
        }

        public Brick(Game game, State[] states, Vector2 position, Bricks parent)
            : base(game)
        {
            // TODO: Construct any child components here
            _position = position;

            _states = states;
            _iCurrentState = 0;

            _parent = parent;
        }

        /// <summary>
        /// Allows the _game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        /// <summary>
        /// Allows the _game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            // Get the current sprite batch
            SpriteBatch sBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

            CurrentState.Draw(sBatch, _position, Color.White);

            base.Draw(gameTime);
        }


        public bool CollidesWithBall(Ball ball)
        {
            Vector2 hitPoint;
            Utility.HitBorder hitBorder;
            bool collided = Utility.Collide(ball.Position, ball.Radius, this.Rectangle, out hitPoint, out hitBorder);
            switch (hitBorder)
            {
                case Utility.HitBorder.Left: case Utility.HitBorder.Right:
                    ball.Velocity = new Vector2(-ball.Velocity.X, ball.Velocity.Y);
                    break;
                case Utility.HitBorder.Top: case Utility.HitBorder.Bottom:
                    ball.Velocity = new Vector2(ball.Velocity.X, -ball.Velocity.Y);
                    break;
            }
            return collided;
        }
    }
}

